uniform vec4 fvAmbient;
uniform vec4 fvSpecular;
uniform vec4 fvDiffuse;
uniform float fSpecularPower;

uniform samplerCube skyBox;
uniform sampler2D Noise;

uniform sampler2D baseMap;
uniform sampler2D bumpMap;

uniform float fTime0_X;

varying vec2 Texcoord;
varying vec2 Texcoord2;
varying vec3 ViewDirection;
varying vec3 LightDirection;

void main( void )
{
   vec2 tcoord = Texcoord2;
   tcoord.x +=  fTime0_X;
   tcoord.y +=  fTime0_X;

   vec4 noisy = texture2D(Noise, tcoord);

   // Signed noise 
   vec3 bump = 2.0 * noisy.xyz - 1.0;
   bump.xy *= 0.15;
   
   // Make sure the normal always points upwards
   bump.z = 0.8 * abs(bump.z) + 0.2;
   
   // Offset the surface normal with the bump

   vec3  fvLightDirection = normalize( LightDirection );
   vec3  fvNormal         = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 );
   float fNDotL           = dot( fvNormal, fvLightDirection ); 
   
   vec3  fvReflection     = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); 
   vec3  fvViewDirection  = normalize( ViewDirection );
   float fRDotV           = max( 0.0, dot( fvReflection, fvViewDirection ) );
   
   vec4  fvBaseColor      = texture2D( baseMap, Texcoord );
   
   vec4  fvTotalAmbient   = fvAmbient * fvBaseColor; 
   vec4  fvTotalDiffuse   = fvDiffuse * fNDotL * fvBaseColor; 
   vec4  fvTotalSpecular  = fvSpecular * ( pow( fRDotV, fSpecularPower ) );

   // Find the reflection vector
   bump = normalize(fvNormal + bump);
   vec3 reflVec = reflect(ViewDirection, bump );
   
   vec4 refl = textureCube(skyBox, reflVec);
  
   gl_FragColor = ((fvTotalAmbient + fvTotalDiffuse)*0.4 + (refl + fvTotalSpecular)*0.6);
       
}